<!-- 上传组件  -->
<template>
    <div class="file-upload">
        <div class="file-upload-container" @click.prevent="triggerUpload" v-bind="$attrs">
            <slot name="loading" v-if="fileStatus =='loading'">
                <button class="btn btn-primary" disabled>正在上传...</button>
            </slot>

             <slot name="uploaded" :uploaderData="uploaderData" v-else-if="fileStatus =='success'">
                <button class="btn btn-primary">上传成功</button>
            </slot>
            
             <slot name="default" v-else>
                <button class="btn btn-primary">点击上传</button>
            </slot>
        </div>
        <!-- <button class="btn btn-primary"  @click.prevent="triggerUpload" v-if="fileStatus =='ready'">点击上传</button>
        <button class="btn btn-primary" disabled v-if="fileStatus == 'loading'">正在上传中……</button>
        <button class="btn btn-primary" @click.prevent="triggerUpload" v-if="fileStatus == 'success'">上传成功</button> -->
        <input
            type="file"
            class="file-input d-none"
            ref="fileInput"
            @change="handleFileChange"
        >
  </div>
</template>

<script lang='ts'>
import { defineComponent, ref, PropType, computed } from 'vue';
import axios from 'axios';
// 上传过程状态
type UploadStatus = "ready" | "loading" | "success" | 'error'
// beforeUpload: 定义beforeUpload
type CheckFunction = (file: File) => boolean
export default defineComponent({
   name: 'upload',
   props: {
       action: {
           type: String,
           required: true
       },
       
       // 一个函数，传入元素file对象，返回一个boolean类型
       beforeUpload: {
           type: Function as PropType<CheckFunction>,
       },
   },
   inheritAttrs: false,
   // 上传成功、上传失败
   emits: ['file-uploader', 'file-uploader-error'],
   components: {

   },

   setup(props, context) {
       const fileInput = ref<null | HTMLInputElement>(null)
       const fileStatus = ref<UploadStatus>('ready');
       const uploaderData = ref();
       const triggerUpload = () => {
           if(fileInput.value) {
               fileInput.value.click();
           }
       }

       const handleFileChange = (e: Event) => {
           const currentTarget = e.target as HTMLInputElement;
           const files = currentTarget.files;
           if(files) {
               // 添加上传前检查逻辑
               if( props.beforeUpload ){
                   const result = props.beforeUpload(files[0]);
                   if(!result) {
                       return;
                   }
               }

               fileStatus.value = 'loading';
               const formData = new FormData();
               formData.append('file', files[0]);
        
               // TOTO 调用接口上传
               setTimeout(() => {
                   fileStatus.value = 'success';
               },1000)
               
               // 上传成功后fileInput清空
               setTimeout(() => {
                   if(fileInput.value) {
                       fileInput.value.value = ''
                   }
                   // 返回数据格式
                   const rawData = {
                       code: 200,
                       msg: '上传成功',
                       data: {
                           _id: '1330683080012984321',
                           url: 'http://218.94.57.151:1521/yczhgc/upload/20210112/6240fbbb897d2a80459e9c4aa4b99ba1.png',
                           createdAt: '2021-03-01 00:00:00',
                       },
                       success: true
                   }
                    uploaderData.value = rawData;
                    context.emit('file-uploader', rawData )
               },2000)

               /*axios.post(props.action, formData, {
                   headers: {
                       'Content-type': 'multipart/form-data'
                   }
               }).then(resp => {
                   console.log('resp==', resp.data);
                   fileStatus.value = 'success';
                   context.emit('file-uploader',resp.data )
               }).catch( err => {
                   fileStatus.value = 'error'
                      context.emit('file-uploader-error',{ err } )
               }).finally( () => {
                   if(fileInput.value) {
                       fileInput.value.value = ''
                   }
               })*/
           }
       }

       return {
           fileInput,
           triggerUpload,
           fileStatus,
           handleFileChange,
           uploaderData
       }
   },
})
</script>
<style lang='scss' scoped>
</style>